package cn.easyplatform.studio.dao.impl;

import cn.easyplatform.studio.dao.DaoException;
import cn.easyplatform.studio.dao.DaoUtils;
import cn.easyplatform.studio.dao.Dialect;
import cn.easyplatform.studio.dao.LinkDao;
import cn.easyplatform.studio.dao.transaction.JdbcTransactions;
import cn.easyplatform.studio.vos.LinkVo;
import org.zkoss.lang.Strings;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public abstract class AbstractLinkDao implements LinkDao {
    private DataSource ds;

    public AbstractLinkDao(DataSource dataSource) {
        this.ds = dataSource;
    }

    protected abstract Dialect getDialect();

    @Override
    public List<LinkVo> getLink(String table) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("select entityId,childrenEntityId,entityName,entityType,entitySubType" +
                    ",entityDesp,createDate,updateDate,createUser,updateUser,status from " + table + " where 1=1 ");
            rs = pstmt.executeQuery();
            List<LinkVo> list = new ArrayList<>();
            while (rs.next()) {
                LinkVo vo = new LinkVo(rs.getString(1),rs.getString(2),
                        rs.getString(3),rs.getString(4), rs.getString(5),
                        rs.getString(6), rs.getDate(7), rs.getDate(8),
                        rs.getString(9), rs.getString(10), rs.getString(11));
                list.add(vo);
            }
            return list;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public LinkVo getLinkWithEntityId(String table, String entityId) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("select entityId,childrenEntityId,entityName,entityType,entitySubType," +
                    "entityDesp,createDate,updateDate,createUser,updateUser,status from " + table + " where entityId=? AND 1=1 ");
            pstmt.setString(1, entityId);
            rs = pstmt.executeQuery();
            LinkVo vo = null;
            while (rs.next()) {
                vo = new LinkVo(rs.getString(1),rs.getString(2),
                        rs.getString(3),rs.getString(4), rs.getString(5),
                        rs.getString(6), rs.getDate(7), rs.getDate(8),
                        rs.getString(9), rs.getString(10), rs.getString(11));
            }
            return vo;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public boolean addLink(String table, LinkVo vo) {
        if (vo == null)
        {
            return false;
        }
        synchronized (vo){
            PreparedStatement pstmt = null;
            Connection conn = null;
            try {
                conn = JdbcTransactions.getConnection(ds);
                pstmt = conn
                        .prepareStatement("insert into " + table +
                                " (`entityId`, `childrenEntityId`, `entityName`, `entityType`, `entitySubType`, `entityDesp`, `createUser`, `status`) " +
                                "values(?,?,?,?,?,?,?,?)");
                pstmt.setString(1, vo.getEntityId());
                pstmt.setString(2, vo.getChildrenEntityId());
                pstmt.setString(3, vo.getEntityName());
                pstmt.setString(4, vo.getEntityType());
                pstmt.setString(5, vo.getEntitySubType());
                pstmt.setString(6, vo.getEntityDesp());
                pstmt.setString(7, vo.getCreateUser());
                pstmt.setString(8, vo.getStatus());
                pstmt.executeUpdate();
            } catch (SQLException ex) {
                throw new DaoException(ex.getMessage());
            } finally {
                DaoUtils.closeQuietly(pstmt);
            }
        }
        return true;
    }

    @Override
    public boolean deleteLink(String table, String entityId) {
        if (Strings.isBlank(entityId))
        {
            return false;
        }
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            conn = JdbcTransactions.getConnection(ds);
            pstmt = conn
                    .prepareStatement("delete from " + table +
                            " where 1 = 1 and entityId = ?");
            pstmt.setString(1, entityId);
            pstmt.executeUpdate();
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt);
        }
        return true;
    }

    @Override
    public boolean updateLink(String table, LinkVo vo) {
        if (vo == null)
        {
            return false;
        }
        synchronized (vo){
            PreparedStatement pstmt = null;
            Connection conn = null;
            try {
                conn = JdbcTransactions.getConnection(ds);
                pstmt = conn.prepareStatement("UPDATE " + table +
                        " SET childrenEntityId=?,entityName=?,entityType=?,entitySubType=?,entityDesp=?,updateDate=?,updateUser=?,status=? " +
                        "WHERE entityId=?");
                pstmt.setString(1, vo.getChildrenEntityId());
                pstmt.setString(2, vo.getEntityName());
                pstmt.setString(3, vo.getEntityType());
                pstmt.setString(4, vo.getEntitySubType());
                pstmt.setString(5, vo.getEntityDesp());
                pstmt.setTimestamp(6, new Timestamp(System.currentTimeMillis()));
                pstmt.setString(7, vo.getUpdateUser());
                pstmt.setString(8, vo.getStatus());
                pstmt.setString(9, vo.getEntityId());
                pstmt.execute();
            } catch (SQLException ex) {
                throw new DaoException(ex.getMessage());
            } finally {
                DaoUtils.closeQuietly(pstmt);
            }
        }
        return true;
    }

    @Override
    public List<LinkVo> getLinkWithChildrenEntityId(String table, String entityId) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("select entityId,childrenEntityId,entityName,entityType,entitySubType," +
                    "entityDesp,createDate,updateDate,createUser,updateUser,status from " + table +
                    " where childrenEntityId LIKE '%" + entityId + "%' AND 1=1 ");
            rs = pstmt.executeQuery();
            List<LinkVo> list = new ArrayList<>();
            while (rs.next()) {
                LinkVo vo = new LinkVo(rs.getString(1),rs.getString(2),
                            rs.getString(3),rs.getString(4), rs.getString(5),
                            rs.getString(6), rs.getDate(7), rs.getDate(8),
                            rs.getString(9), rs.getString(10), rs.getString(11));
                list.add(vo);
            }
            return list;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }
    @Override
    public boolean updateLinks(String table, List<LinkVo> voList) {
        if (voList == null || voList.size() == 0)
        {
            return false;
        }
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("UPDATE " + table +
                    " SET childrenEntityId=?,entityName=?,entityType=?,entitySubType=?,entityDesp=?,updateDate=?,updateUser=?,status=?" +
                    "WHERE entityId=?");
            for (LinkVo vo : voList) {
                pstmt.setString(1, vo.getChildrenEntityId());
                pstmt.setString(2, vo.getEntityName());
                pstmt.setString(3, vo.getEntityType());
                pstmt.setString(4, vo.getEntitySubType());
                pstmt.setString(5, vo.getEntityDesp());
                pstmt.setTimestamp(6, new Timestamp(System.currentTimeMillis()));
                pstmt.setString(7, vo.getUpdateUser());
                pstmt.setString(8, vo.getStatus());
                pstmt.setString(9, vo.getEntityId());
                pstmt.addBatch();
            }
            pstmt.executeBatch();
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt);
        }
        return true;
    }
}
